from django.contrib.auth.hashers import make_password, check_password
from rest_framework.pagination import PageNumberPagination
from rest_framework_simplejwt.exceptions import TokenError
from rest_framework_simplejwt.tokens import RefreshToken

from apps.common.send_sms_4a import send_sms_code
from apps.system.filters import  OperationRecordFilter, LoginLogFilter
from apps.system.md5 import decode
from apps.system.models import Region, OperationRecord, Organization
from apps.system.schemas import SMSGetTokenRequest, SMSRequest
from apps.system.serializers import RegionsSerializer, OperationRecordSerializer, LoginLogSerializer, \
    OrganizationSerializer
from configs.sms_4A import SEND_SMS_METHOD, APP_ID, APP_ID_Evaluation
from extensions.common.schema import *
from extensions.common.base import *
from extensions.permissions import *
from extensions.exceptions import *
from extensions.viewsets import *
from apps.system.serializers import *
from apps.system.schemas import *
from apps.system.models import *
from apps.common.com import Pagination
from rest_framework import status, filters


class PaginationCls(PageNumberPagination):
    page_size = 15
    page_size_query_param = 'page_size'
    page_query_param = 'page'
    max_page_size = 100000

#选项分页
class OptionPaginationCls(PageNumberPagination):
    page_size = 99999
    page_size_query_param = 'page_size'
    page_query_param = 'page'
    max_page_size = 100000

class PermissionGroupViewSet(BaseViewSet, ListModelMixin):
    """权限分组"""

    serializer_class = PermissionGroupSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = None
    ordering = ['id']
    queryset = PermissionGroup.objects.all()

    def get_queryset(self):
        return self.queryset.prefetch_related('permissions').all()

class SystemConfigViewSet(BaseViewSet, ListModelMixin):
    """权限分组"""

    serializer_class = PermissionGroupSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = None
    ordering = ['id']
    queryset = PermissionGroup.objects.all()

    def get_queryset(self):
        return self.queryset.prefetch_related('permissions').all()


class RoleViewSet(ModelViewSet):
    """角色"""

    serializer_class = RoleSerializer
    permission_classes = [IsAuthenticated, IsManagerPermission]
    pagination_class = Pagination
    search_fields = ['name']
    queryset = Role.objects.all()

    @transaction.atomic
    def perform_update(self, serializer):
        role = serializer.save()

        # 同步用户权限
        users = role.users.prefetch_related('roles', 'roles__permissions').all()
        for user in users:
            permissions = {permission.code for role in user.roles.all()
                           for permission in role.permissions.all()}
            user.permissions = list(permissions)
        else:
            User.objects.bulk_update(users, ['permissions'])

    @transaction.atomic
    def perform_destroy(self, instance):
        users = instance.users.all()
        instance.delete()

        # 同步用户权限
        for user in users.prefetch_related('roles', 'roles__permissions').all():
            permissions = {permission.code for role in user.roles.all()
                           for permission in role.permissions.all()}
            user.permissions = list(permissions)
        else:
            User.objects.bulk_update(users, ['permissions'])


class OperationRecordsPagination(PageNumberPagination):
    page_size = 15
    page_size_query_param = 'page_size'
    page_query_param = 'current'
    max_page_size = 100000


class OperationRecordsViewSet(ModelViewSet):
    """操作日志"""
    serializer_class = OperationRecordSerializer
    # permission_classes = [IsAuthenticated, IsManagerPermission]
    permission_classes = [IsAuthenticated]
    pagination_class = OperationRecordsPagination
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = OperationRecordFilter
    search_fields = ['user__name','url_name']
    ordering_fields = ['id','create_time']
    queryset = OperationRecord.objects.filter(del_flag=False)


class LoginLogsViewSet(ModelViewSet):
    """登录日志"""
    serializer_class = LoginLogSerializer
    # permission_classes = [IsAuthenticated, IsManagerPermission]
    permission_classes = [IsAuthenticated]
    pagination_class = OperationRecordsPagination
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = LoginLogFilter
    search_fields = ['user__name','ip_address','user_agent']
    ordering_fields = ['id','create_time']
    queryset = LoginLog.objects.all()


class JobsViewSet(ModelViewSet):
    """职务"""
    serializer_class = JobsSerializer
    # permission_classes = [IsAuthenticated, IsManagerPermission]
    # permission_classes = [IsAuthenticated]
    pagination_class = PaginationCls
    search_fields = ['name']
    ordering_fields = ['id','name','index']
    queryset = Job.objects.all()


class DictsViewSet(ModelViewSet):
    """职务"""
    serializer_class = DictsSerializer
    # permission_classes = [IsAuthenticated, IsManagerPermission]
    # permission_classes = [IsAuthenticated]
    pagination_class = OptionPaginationCls
    search_fields = ['name']
    ordering_fields = ['id','name',]
    queryset = Dict.objects.all()

    def get_queryset(self):
        qs = super().get_queryset()
        sys_name = self.request.GET.get('sys_name', None)  # 获取前端传来的sys_name参数
        if sys_name:
            qs = qs.filter(id__contains=sys_name) # 过滤出id包含sys_name的Dict对象
        return qs.prefetch_related('dict_item').order_by('dict_item__index')


class RegionsViewSet(ModelViewSet):
    serializer_class = RegionsSerializer
    pagination_class = PaginationCls
    search_fields = ['name']
    ordering_fields = ['id','name','index']
    queryset = Region.objects.all()
    #把数据组装成市、区县的列表格式
    def list(self, request):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        # print(len(serializer.data))
        # 遍历出每个order item
        quxians =[]
        for item in serializer.data:
            if item['region_level']==2:
                children = []
                for quxian in serializer.data:
                    if item['id']==quxian['region_parent_id']:
                        quxian['value'] = quxian['id']
                        quxian['label'] = quxian['region_name']
                        quxian.pop('id')
                        quxian.pop('region_name')
                        children.append(quxian)
                    item['children']=children
                item['value']=item['id']
                item['label']=item['region_name']
                item.pop('id')
                item.pop('region_name')
                quxians.append(item)
            # 将order中的'sales_goods_items'中的'clAmount'、'jgAmount'进行求和clAmount_sum、jgAmount_sum
        print(quxians)
        data={
            "results":quxians
        }
        return Response(data=data, status=status.HTTP_200_OK)


class UserViewSet(ModelViewSet):
    """用户"""

    serializer_class = UserSerializer
    # permission_classes = [IsAuthenticated, IsManagerPermission]
    pagination_class = Pagination
    filterset_fields = ['is_active']
    search_fields = ['username', 'name', 'phone', 'email']
    ordering_fields = ['id', 'username', 'name']
    queryset = User.objects.all()

    def perform_destroy(self, instance):
        if instance.is_manager:
            raise ValidationError('无法删除管理员账号')

        try:
            instance.delete()
        except ProtectedError:
            raise ValidationError(f'用户[{instance.username}]已被引用, 无法删除')

    @extend_schema(request=None, responses={200: None})
    @action(detail=True, methods=['post'])
    def reset_password(self, request, *args, **kwargs):
        """重置密码"""

        instance = self.get_object()
        instance.password = make_password(self.user.username)
        instance.save(update_fields=['password'])

        return Response(status=status.HTTP_200_OK)


class OrganizationViewSet(ModelViewSet):
    """组织"""

    serializer_class = OrganizationSerializer
    # permission_classes = [IsAuthenticated, IsManagerPermission]
    pagination_class = Pagination
    filterset_fields = ['name']
    search_fields = ['name']
    ordering_fields = ['index']
    queryset = Organization.objects.all()

    def get_queryset(self):
        # 只获取没有父组织的组织
        return Organization.objects.filter(parent__isnull=True)




class UserActionViewSet(FunctionViewSet):
    """用户操作"""
    # 发送短信验证码 18308576111
    # @extend_schema(request=None, responses={200: None})
    @extend_schema(request=SMSRequest, responses={200: GetTokenResponse})
    @action(detail=False, methods=['post'])
    def send_sms(self, request, *args, **kwargs):
        serializer = SMSRequest(data=request.data)
        serializer.is_valid(raise_exception=True)
        validated_data = serializer.validated_data
        phone_num=decode(validated_data['mobile'],'mobile')
        sys_name=validated_data['sys_name']
        if not (user := User.objects.filter(phone=phone_num).first()):
            raise ValidationError('用户不存在')
        data = request.data
        try:
            App_ID_New = APP_ID
            if sys_name == 'Evaluation':
                App_ID_New = APP_ID_Evaluation
            mobile = phone_num
            data = {
                "method": SEND_SMS_METHOD,
                "appid": App_ID_New,
                "masterAcc": mobile,
            }
            resp = send_sms_code(data)
        except Exception as e:
            print(e)
            raise ValidationError("获取验证码失败，请检查手机号码是否正确或是否已经申请了VPN权限！")
        return Response(resp)

    # 短信验证码版
    @extend_schema(request=GetTokenRequest, responses={200: GetTokenResponse})
    @action(detail=False, methods=['post'])
    def get_token(self, request, *args, **kwargs):
        """获取令牌"""
        serializer = SMSGetTokenRequest(data=request.data)
        serializer.is_valid(raise_exception=True)
        validated_data = serializer.validated_data
        mobile = decode(validated_data['mobile'], 'mobile')
        sys_name = validated_data['sys_name']
        if not (user := User.objects.filter(phone=mobile).first()):
            raise ValidationError('用户不存在')

        # try:
        #     App_ID_New = APP_ID
        #     if sys_name == 'Evaluation':
        #         App_ID_New = APP_ID_Evaluation
        #     code = decode(validated_data['code'],'code')
        #     data = {
        #         "method": AUTH_SMS_METHOD,
        #         "appid": App_ID_New,
        #         "masterAcc": mobile,
        #         "smsPwd": code,
        #     }
        #     resp = send_sms_code(data)
        #     result = resp['SSO']['RESULT']
        #     result_msg = resp['SSO']['RESULT_MSG']
        #     if(result=='0'):
        #         raise ValidationError(result_msg)
        # except Exception as e:
        #     raise ValidationError(result_msg)

        if not user.is_active and not user.is_manager:
            raise ValidationError('用户未激活')
        token = RefreshToken()
        # user = request.user
        ip_address = request.META.get('REMOTE_ADDR')
        user_agent = request.META.get('HTTP_USER_AGENT')
        login_log = LoginLog(user=user, ip_address=ip_address, user_agent=user_agent)
        login_log.save()
        token['user_id'] = user.id
        data = {'refresh': str(token), 'access': str(token.access_token)}

        return Response(data=data, status=status.HTTP_200_OK)

    # @extend_schema(request=GetTokenRequest, responses={200: GetTokenResponse})
    # @action(detail=False, methods=['post'])
    # def get_token(self, request, *args, **kwargs):
    #     """获取令牌"""
    #     serializer = GetTokenRequest(data=request.data)
    #     # print(User.objects.filter(username=validated_data['username']).first())
    #     serializer.is_valid(raise_exception=True)
    #     validated_data = serializer.validated_data
    #     if not (user := User.objects.filter(username=validated_data['username']).first()):
    #         raise ValidationError('用户不存在')
    #
    #     if not check_password(validated_data['password'], user.password):
    #         raise AuthenticationFailed('密码错误')
    #
    #     if not user.is_active and not user.is_manager:
    #         raise ValidationError('用户未激活')
    #
    #     token = RefreshToken()
    #     token['user_id'] = user.id
    #     data = {'refresh': str(token), 'access': str(token.access_token)}
    #
    #     return Response(data=data, status=status.HTTP_200_OK)

    @extend_schema(request=RefreshTokenRequest, responses={200: RefreshTokenResponse})
    @action(detail=False, methods=['post'])
    def refresh_token(self, request, *args, **kwargs):
        """刷新令牌"""

        serializer = RefreshTokenRequest(data=request.data)
        serializer.is_valid(raise_exception=True)
        validated_data = serializer.validated_data

        try:
            token = RefreshToken(validated_data['refresh'])
        except TokenError:
            raise NotAuthenticated('令牌失效')

        data = {'access': str(token.access_token)}
        return Response(data=data, status=status.HTTP_200_OK)

    @extend_schema(responses={200: UserInfoResponse})
    @action(detail=False, methods=['get'], permission_classes=[IsAuthenticated])
    def info(self, request, *args, **kwargs):
        """用户信息"""

        serializer = UserInfoResponse(instance=self.user)
        return Response(data=serializer.data, status=status.HTTP_200_OK)



__all__ = [
    'PermissionGroupViewSet',
    'SystemConfigViewSet',
    'JobsViewSet',
    'DictsViewSet',
    'RoleViewSet', 'UserViewSet', 'UserActionViewSet',

]
